package session;

import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import javax.ejb.Stateful;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceUnit;
import rental.CarRentalCompany;
import rental.Quote;
import rental.Reservation;
import rental.ReservationConstraints;
import rental.ReservationException;

/**
 *
 * @author wouterdb
 */
@Stateful
public class CarRentalSession implements CarRentalSessionRemote {

    @PersistenceUnit
    private EntityManagerFactory emf;
    private EntityManager em;
    
    private String client;
    private List<Quote> quotes = new LinkedList<Quote>();

    public CarRentalSession() {
        em = emf.createEntityManager();
    }

    @Override
    public Set<String> getAllRentalCompanies() {
        return new HashSet<String>(em.createNamedQuery("SELECT comp.name FROM Company comp", String.class).getResultList());
    }

    @Override
    public Quote createQuote(String company, ReservationConstraints constraints) throws ReservationException {
        CarRentalCompany comp = getCompany(company);
        Quote out = comp.createQuote(constraints, client);
        quotes.add(out);
        return out;
    }


    @Override
    public List<Quote> getCurrentQuotes() {
        return quotes;
    }

    private CarRentalCompany getCompany(String name){
        return em.createNamedQuery("SELECT comp FROM Company comp WHERE comp.name = :companyName", CarRentalCompany.class).setParameter("companyName", name).getSingleResult();
    }
    
    @Override
    public List<Reservation> confirmQuotes() throws ReservationException {
        List<Reservation> done = new LinkedList<Reservation>();
        try {
            for (Quote quote : quotes) {
                done.add(this.getCompany(quote.getRentalCompany()).confirmQuote(quote));
            }
        } catch (ReservationException e) {
            for(Reservation r:done)
                this.getCompany(r.getRentalCompany()).cancelReservation(r);
            throw e;
        }
        return done;
    }

    @Override
    public void setClientName(String name) {
        if (client != null) {
            throw new IllegalStateException("name already set");
        }
        client = name;
    }
}
